package com.vaadin.demo.workoutlog.filters;

import org.apache.cayenne.BaseContext;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.conf.ServletUtil;
import org.apache.cayenne.conf.WebApplicationContextFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: Dmitry Zhuravlev
 * Date: 16/05/11
 * Time: 13:11
 * Wrapper filter class
 */
public class ContextFilter extends WebApplicationContextFilter {
  private final static Log log = LogFactory
    .getLog(ContextFilter.class);


  /**
   * The main worker method that binds a DataContext to the current
   * thread on entry and unbinds it on exit (regardless of whether any
   * exceptions occurred in the request).
   */
  public void doFilter(ServletRequest request,
                       ServletResponse response, FilterChain chain) throws IOException,
                                                                           ServletException {

    boolean reset = false;

    if (request instanceof HttpServletRequest) {
      reset = true;

      HttpSession session = ((HttpServletRequest)request)
        .getSession(true);
      DataContext context = ServletUtil.getSessionContext(session);

      BaseContext.bindThreadObjectContext(context);
    }

    try {
      chain.doFilter(request, response);
    }
    finally {

      if (reset) {
        // we need rollback because if we don't do this, context
        // become "dirty" and will be cache effect
        if (BaseContext.getThreadObjectContext().hasChanges()) {
          BaseContext.getThreadObjectContext().rollbackChanges();
        }
        BaseContext.bindThreadObjectContext(null);
      }
    }
  }
}
